package com.ldu.exam.service;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.ldu.exam.assistant.BeanAssistant;
import com.ldu.exam.dao.QuestionTypeRepository;
import com.ldu.exam.dao.TestQuestionRepository;
import com.ldu.exam.model.QuestionTypeModel;
import com.ldu.exam.model.TestQuestionModel;

@Service
public class TestQuestionService {
	@Autowired TestQuestionRepository repository;
	@Autowired QuestionTypeRepository questionTypeRepository;
	
	public List<TestQuestionModel> findAllNoPage()
	{
		return this.repository.findAll();
	}
	
	public Page<TestQuestionModel> findAll(Pageable page)
	{
		return this.repository.findAll(page);
	}
	
	public List<QuestionTypeModel> getDropList()
	{
		return this.questionTypeRepository.findAll();
	}
	
	public TestQuestionModel findQuestionId(String id)
	{
		return this.repository.findById(id).orElse(null);
	}
	
	public QuestionTypeModel findById(String id)
	{
		return this.questionTypeRepository.findById(id).orElse(null);
	}
	
	public TestQuestionModel add(TestQuestionModel model)
	{
		return this.repository.save(model);
	}
	
	public void delete(String id)
	{
		TestQuestionModel model = new TestQuestionModel();
		model.setId(id);
		this.repository.delete(model);
	}
	
	public Object update(String id,TestQuestionModel model)
	{
		model.setId(null);
		TestQuestionModel origin = this.repository.findById(id).orElse(null);
		String [] nullPropertyNameStrings = BeanAssistant.getNullPropertyNames(model);
		BeanUtils.copyProperties(model, origin, nullPropertyNameStrings);
		return this.repository.save(origin);
	}
	
	public Page<TestQuestionModel> findByQuestionTypeId(String questionTypeId,Pageable page)
	{
		return this.repository.findByTypeId(questionTypeId,page);
	}
	
	public Page<TestQuestionModel> findByName(String name,int page ,int size)
	{
		return StringUtils.isEmpty(name) ? this.repository.findAll(PageRequest.of(page, size))
				: this.repository.findByTitleContaining(name, PageRequest.of(page, size));
	}
	
	public Page<TestQuestionModel> findByBoth(String title,String questionTypeId,int page ,int size)
	{
//		Page<TestQuestionModel> pageList = StringUtils.isEmpty(title) ? this.repository.findAll(PageRequest.of(page, size))
//				: this.repository.findByTitleContaining(title, PageRequest.of(page, size));
		TestQuestionModel model  = new TestQuestionModel();
		model.setTitle(title);
		QuestionTypeModel qtmodel = new QuestionTypeModel();
		qtmodel.setId(questionTypeId);
		model.setQuestionType(qtmodel);
		return this.findByCondition(model, PageRequest.of(page, size));
	}
	
	private Page<TestQuestionModel> findByCondition(TestQuestionModel model,Pageable page)
	{
		return this.repository.findAll(new Specification<TestQuestionModel>() {
			private static final long serialVersionUID = 1L;
			@Override
			public Predicate toPredicate(Root<TestQuestionModel> root,CriteriaQuery<?> query,CriteriaBuilder builder)
			{
				List<Predicate> list = new ArrayList<Predicate>();
				if(!StringUtils.isEmpty(model.getTitle()))
					list.add(builder.like(root.<String>get("title"),"%"+model.getTitle()+"%"));
				
				list.add(builder.equal(root.<String>get("questionType").<String>get("id"), model.getQuestionType().getId()));
				return builder.and(list.toArray(new Predicate[list.size()]));
			}
		}, page);
	}
}
